/*
 * logger.c
 *
 *  Created on: 01.06.2012.
 *      Author: Aco
 */

#include "../portutil/threading.h"
#include "../portutil/sockets.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#define LMAX (100)

int logID = 0;

int connPort = 0;
CUSocket *lsockets[LMAX] = {0};
FILE *lfiles[LMAX] = {0};
char *lFileName = NULL;
CUMutex *regMutex = NULL;
char *lAddress = NULL;

// Logovanje ide na stdout, na socket, ako je naveden, i u fajlove, ako je naveden pattern
void l_init(const char * address, int port, const char * fileName)
{
	if(address != NULL)
	{
		lAddress = (char*)malloc(strlen(address) + 1);
		strcpy(lAddress, address);
	}

	connPort = port;

	if(fileName != NULL)
	{
		lFileName = (char*)malloc(strlen(fileName) + 1);
		strcpy(lFileName, fileName);
	}
	regMutex = cu_createMutex();
}

// Zahtjev za loggerom, pripremaju se fajl i socket i dodjeljuje se ID
int l_register()
{
	int retVal;
	cu_lockMutex(regMutex);

	logID++;
	retVal = logID;

	if(lFileName)
	{
		char name[256];
		sprintf(name, lFileName, logID);
		lfiles[logID] = fopen(name, "wt");
	}

	if(connPort > 0 && lAddress != NULL)
	{
		lsockets[logID] = cu_createTCPSocket();
		if(cu_openClientSocket(lsockets[logID], lAddress, connPort) == CU_ERROR)
		{
			cu_closeSocket(lsockets[logID]);
			free(lsockets[logID]);
			lsockets[logID] = NULL;
		}
	}
	cu_unlockMutex(regMutex);

	return retVal;
}

// Ekvivalent puts-a, samo na tri kanala
void lputs(int id, const char * text)
{
	puts(text);		// stdout
	fflush(stdout);

	if(id > 0 && id < LMAX)
	{
		if(lfiles[id] != NULL)		// fajl
			fputs(text, lfiles[id]);

		if(lsockets[id] != NULL)	// mreza
		{
			char buffer[512];
			int len = strlen(text);
			buffer[0] = 1;
			buffer[1] = len + 2;
			strcpy(buffer + 2, text);
			buffer[len + 2] = '\n';
			buffer[len + 3] = '\0';
			cu_sendData(lsockets[id], buffer, strlen(text) + 4);
		}
	}
}

// Postavlja naslov taba u GeoTerminalu
void l_setTitle(int id, const char * title)
{
	if(id > 0 && id < LMAX)
	{
		if(lsockets[id] != NULL)
		{
			char buffer[512];
			buffer[0] = 2;
			buffer[1] = strlen(title) + 1;
			strcpy(buffer + 2, title);
			cu_sendData(lsockets[id], buffer, strlen(title) + 3);
		}
	}
}

// Registruje dolazni port u GeoTerminalu
void l_registerPort(int id, int port)
{
	if(id > 0 && id < LMAX)
	{
		if(lsockets[id] != NULL)
		{
			char buffer[512];
			buffer[0] = 3;
			sprintf(buffer + 2, "%d", port);
			buffer[1] = strlen(buffer + 2) + 1;
			cu_sendData(lsockets[id], buffer, strlen(buffer + 1) + 2);
		}
	}
}

// Ekvivalent printf-a, daje gotov string lputs-u
void lprintf(int id, const char * fmt, ...)
{
	char buffer[512];
	va_list argp;
	va_start(argp, fmt);
	vsprintf(buffer, fmt, argp);
	va_end(argp);
	lputs(id, buffer);
}

// Gasi logger po ID-u
void l_disconnect(int id)
{
	if(id > 0 && id < LMAX)
	{
		if(lsockets[id] != NULL)	// Zatvara socket
		{
			cu_closeSocket(lsockets[id]);
			free(lsockets[id]);
			lsockets[id] = NULL;
		}

		if(lfiles[id] != NULL)		// Zatvara file
		{
			fclose(lfiles[id]);
			lfiles[id] = NULL;
		}
	}
}

// Gasi sve loggere
void l_shutdown()
{
	int i;
	for(i = 0; i < LMAX; ++i)
		l_disconnect(i);
}
